﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lucene.Net.Store;
using Lucene.Net.Search;
using ObjectSearch.Configuration;
using Lucene.Net.QueryParsers;
using Lucene.Net.Highlight;

namespace ObjectSearch
{
    public class LuceneIndex : LuceneObjectSearchBase, IIndex
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="LuceneIndex"/> class.
        /// </summary>
        public LuceneIndex(string indexDirectory, Configuration.Configuration configuration)
            : base(new IndexSettings() { Directory = FSDirectory.GetDirectory(indexDirectory, false) }, configuration)
        {

        }

        public LuceneIndex(IndexSettings settings, Configuration.Configuration configuration)
            : base(settings, configuration)
        {

        }

        //public PagedSearchResult<T> SearchPaged(string queryString, int itemsPerPage)
        //{
        //    string searchField = null;
        //    List<SortField> sortFieldsList = new List<SortField>();

        //    ObjectMetaData objectMeta = this.Configuration.FindMetaData<T>();

        //    foreach (FieldMetaData field in objectMeta.Fields)
        //    {
        //        //set the field name if we havn't yet
        //        if (searchField == null)
        //        {
        //            searchField = field.FieldName;
        //        }

        //        //over write anything that is set as default search field.
        //        if (field.IsDefaultSearchField)
        //        {
        //            searchField = field.FieldName;
        //        }

        //        if (field.SortingOptions == SortOptions.Sort)
        //            sortFieldsList.Add(new SortField(field.FieldName));
        //        if (field.SortingOptions == SortOptions.SortDescending)
        //            sortFieldsList.Add(new SortField(field.FieldName, true));
        //    }

        //    QueryParser parser = new QueryParser(searchField, IndexSettings.Analyzer);

        //    parser.SetDefaultOperator(QueryParser.AND_OPERATOR);

        //    Query query = parser.Parse(queryString);

        //    Searcher searcher = new IndexSearcher(IndexSettings.Directory);

        //    Hits hits;

        //    if (sortFieldsList.Count == 0)
        //        hits = searcher.Search(query);
        //    else
        //    {
        //        Sort s = new Sort(sortFieldsList.ToArray());
        //        hits = searcher.Search(query, s);
        //    }

        //    return new PagedSearchResult<T>(hits, 0, itemsPerPage, Configuration);
        //}

        #region IIndex Members

        public IIndexWriter CreateWriter<T>()
        {
            return new LuceneIndexWriter<T>(this.IndexSettings, this.Configuration);
        }

        public IPagedSearchResults<T> SearchPagedResult<T>(string queryString, int itemsPerPage)
        {
            string searchField = null;
            List<SortField> sortFieldsList = new List<SortField>();

            ObjectMetaData objectMeta = this.Configuration.FindMetaData<T>();

            foreach (FieldMetaData field in objectMeta.Fields)
            {
                //set the field name if we havn't yet
                if (searchField == null)
                {
                    searchField = field.FieldName;
                }

                //over write anything that is set as default search field.
                if (field.IsDefaultSearchField)
                {
                    searchField = field.FieldName;
                }

                if (field.SortingOptions == SortOptions.Sort)
                    sortFieldsList.Add(new SortField(field.FieldName));
                if (field.SortingOptions == SortOptions.SortDescending)
                    sortFieldsList.Add(new SortField(field.FieldName, true));
            }
            
            QueryParser parser = new QueryParser(searchField, IndexSettings.Analyzer);

            parser.SetDefaultOperator(QueryParser.AND_OPERATOR);

            Query query = parser.Parse(queryString);

            Searcher searcher = new IndexSearcher(IndexSettings.Directory);

            Hits hits;

            if (sortFieldsList.Count == 0)
                hits = searcher.Search(query);
            else
            {
                Sort s = new Sort(sortFieldsList.ToArray());
                hits = searcher.Search(query, s);
            }

            return new PagedSearchResults<T>(hits, query, 0, itemsPerPage, this.IndexSettings, this.Configuration);
        }

        #endregion

        #region IIndex Members

        public bool Exists
        {
            get 
            {
                return Lucene.Net.Index.IndexReader.IndexExists(IndexSettings.Directory);                
            }
        }

        public void CreateIndex()
        {
            Lucene.Net.Index.IndexWriter temp = new Lucene.Net.Index.IndexWriter(IndexSettings.Directory, IndexSettings.Analyzer, true);
            temp.Close();
        }

        #endregion
    }
}
